package com.ph.finder.client.mapper.ui;

import java.util.List;

import com.google.gwt.core.client.GWT;
import com.google.gwt.event.dom.client.ChangeEvent;
import com.google.gwt.event.dom.client.ChangeHandler;
import com.google.gwt.event.logical.shared.SelectionEvent;
import com.google.gwt.event.logical.shared.SelectionHandler;
import com.google.gwt.maps.client.MapWidget;
import com.google.gwt.maps.client.geocode.Geocoder;
import com.google.gwt.maps.client.geocode.LatLngCallback;
import com.google.gwt.maps.client.geom.LatLng;
import com.google.gwt.uibinder.client.UiBinder;
import com.google.gwt.uibinder.client.UiField;
import com.google.gwt.user.client.Timer;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.FlowPanel;
import com.google.gwt.user.client.ui.HTMLPanel;
import com.google.gwt.user.client.ui.Image;
import com.google.gwt.user.client.ui.InlineLabel;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.SuggestBox;
import com.google.gwt.user.client.ui.Widget;
import com.google.gwt.user.client.ui.SuggestOracle.Suggestion;
import com.ph.finder.client.AddressInfo;
import com.ph.finder.client.CityItem;
import com.ph.finder.client.CitySuggestOracle;
import com.ph.finder.client.PrecinctService;
import com.ph.finder.client.PrecinctServiceAsync;
import com.ph.finder.client.Util;
import com.ph.finder.client.ui.UIUtils;

public class CitySelectLPanel extends Composite {

	private static CitySelectLPanelUiBinder uiBinder = GWT
			.create(CitySelectLPanelUiBinder.class);

	interface CitySelectLPanelUiBinder extends UiBinder<Widget, CitySelectLPanel> {
	}

	@UiField(provided = true)
	SuggestBox city;

	@UiField
	HTMLPanel loadingPane;

	@UiField
	Image spinnerImage;

	@UiField
	InlineLabel loadingLabel;

	@UiField
	Label errorLabel;

	private MapPrecinctRootPage ctr;
	private CityItem selection;
	private final MapWidget maps;

	public CitySelectLPanel(MapPrecinctRootPage ctr, MapWidget maps) {
		this.ctr = ctr;
		this.maps = maps;
		city = new SuggestBox(new CitySuggestOracle());
		initWidget(uiBinder.createAndBindUi(this));

		// Area Handlers
		city.addSelectionHandler(new SelectionHandler<Suggestion>() {
			@Override
			public void onSelection(SelectionEvent<Suggestion> event) {
				selection = (CityItem) event.getSelectedItem();
				city.addStyleName("disabled");

				// Start looking for the place
				initializeArea(selection);
			}
		});
		city.getTextBox().addChangeHandler(new ChangeHandler() {
			@Override
			public void onChange(ChangeEvent event) {
				if (selection != null && city.getStyleName().contains("disabled")) {
					city.getTextBox().setText(selection.getReplacementString());
				}
			}
		});

		Util.track("/MapYourPrecinct/00-Start");
	}

	private void initializeArea(CityItem area) {
		initializeArea(area.getReplacementString(), 12);
	}

	private void initializeArea(final String address, final int zoom) {
		loadingLabel.setText("Retrieving area information...");
		loadingPane.setVisible(true);
		spinnerImage.setVisible(true);

		final String searchAddress = address + ", Philippines";
		Geocoder gcoder = new Geocoder();
		gcoder.setBaseCountryCode("ph");
		final int zoomLevel = zoom;
		gcoder.getLatLng(searchAddress, new LatLngCallback() {

			@Override
			public void onSuccess(LatLng point) {
				Util.track("/MapYourPrecinct/02-AreaSelect");
				maps.setCenter(point, zoomLevel);

				loadingLabel.setText("Retrieving Unmapped Precincts... ");

				getAddressesForMapping(selection);
			}

			@Override
			public void onFailure() {
				if (address.contains(",")) {
					initializeArea(address.substring(address.indexOf(",")), zoom + 1);
				} else {
					Util.track("/MapYourPrecinct/02-AreaSelectFail-" + zoom);
					UIUtils.error(errorLabel, "The area was not found.  Either you entered a too specific area or its incorrectly spelled.  Try cities or towns, like 'cebu'.");
					fail();
				}
			}

		});
	}

	private void getAddressesForMapping(CityItem selection) {
		// populate Province/City keys


		PrecinctServiceAsync service = (PrecinctServiceAsync) GWT.create(PrecinctService.class);
		service.getAddressesOnCity(selection.getRegion(),
				selection.getProvinceKey(),
				selection.getCityKey(),
				true,
				false,
				50,
				new AsyncCallback<List<AddressInfo>>() {

			@Override
			public void onSuccess(List<AddressInfo> results) {
				Util.track("/MapYourPrecinct/04-AreaUnmapped");
				if (results == null || results.size() == 0) {
					UIUtils.error(errorLabel, "The city you have selected has been fully mapped.  Try other cities you are familiar with.");
					fail();
				} else {
					ctr.selectAddressInList(CitySelectLPanel.this.selection, results);
				}
			}

			@Override
			public void onFailure(Throwable caught) {
				Util.track("/MapYourPrecinct/04-AreaUnmappedFail");
				UIUtils.error(errorLabel, "The city/municipality you requested had an error.  Please report this as a problem.");
				fail();
			}

		});
	}

	private void fail() {
		loadingLabel.setText("");
		spinnerImage.setVisible(false);
		resetAfterDelay();
	}

	private void resetAfterDelay() {
		(new Timer() {
			@Override
			public void run() {
				selection = null;
				city.removeStyleName("disabled");
				city.getTextBox().setFocus(true);
				loadingPane.setVisible(false);
			}
		}).schedule(5000);
	}

//	private void loadPrecincts(LatLngBounds bounds, final int requestId) {
//		PrecinctServiceAsync service = (PrecinctServiceAsync) GWT.create(PrecinctService.class);
//
//		service.getPrecinctsInBounds(bounds.getSouthWest().getLatitude(),
//				bounds.getSouthWest().getLongitude(),
//				bounds.getNorthEast().getLatitude(),
//				bounds.getNorthEast().getLongitude(),
//				new AsyncCallback<List<PrecinctInfo>>() {
//
//					@Override
//					public void onSuccess(List<PrecinctInfo> result) {
//						if (requestId != loadPrecinctReqId) {
//							Util.track("/MapYourPrecinct/03-GetPrecinctsCancelled");
//							return;
//						}
//						Util.track("/MapYourPrecinct/03-GetPrecincts");
//
//						loadingPane.setVisible(false);
//
//						if (result.size() == 0) {
//							precinctEmptyPane.setVisible(true);
//						} else {
//							precinctListPane.setVisible(true);
//							// TODO: Display items here
//						}
//						unmappedPane.setVisible(true);
//					}
//
//					@Override
//					public void onFailure(Throwable caught) {
//						if (requestId != loadPrecinctReqId) {
//							Util.track("/MapYourPrecinct/03-GetPrecinctsCancelled");
//							return;
//						}
//						Util.track("/MapYourPrecinct/03-GetPrecinctsFail");
//						loadingLabel.setText("");
//						UIUtils.error(errorLabel, "Failure in getting precinct information.  Please try again later.");
//						resetAfterDelay();
//					}
//				});
//	}


}
